function Vue(config={}){
    const {el,data={},methods={}} = config;
    this.$data = data;
    this.$binds = {};// {str:[订阅者1，订阅者2，订阅者3]}
    // 对数据进行侦听（观察）
    this.observe();
    this.$mount(el);
}

Object.assign(Vue.prototype,{
    $mount(el){
        this.$el = el;
        if(typeof el === "string"){
            this.$el = document.querySelector(el);
        }
        if(this.$el){
            this.compile();
        }
    },
    observe(){
        for(let key in this.$data){
            this.$binds[key] = [];
            Object.defineProperty(this,key,{
                get(){
                    return this.$data[key];
                },
                set(v){
                    this.$data[key] = v;
                    // 发布消息给订阅者
                    this.$binds[key].forEach(update=>update(v))
                }
            })
        }
    },
    // 解析模板
    compile(){
        for(let i=0;i<this.$el.children.length;i++){
            // 获取节点
            const node = this.$el.children[i];
            // 判断有没有使用指令v-model
            if(node.hasAttribute("v-model")){
                // 1- 增加了input事件
                node.addEventListener("input",function(e){
                    this[value] = e.target.value;
                }.bind(this))
                // data中的属性名
                const value = node.getAttribute("v-model");
                // 2- 绑定了数据
                node.value = this[value];
                // 生成订阅者，负责更新node.value属性值
                this.$binds[value].push(new Watcher(node,"value"))
            }
            // 判断node是否拥有指令v-html
            if(node.hasAttribute("v-html")){
                const value = node.getAttribute("v-html");
                node.innerHTML = this[value];
                // 生成订阅者，负责更新node.innerHTML
                this.$binds[value].push(new Watcher(node,"innerHTML"))
            }
            // 判断node是否拥有指令v-text
            if(node.hasAttribute("v-text")){
                const value = node.getAttribute("v-text");
                node.innerText = this[value];
                // 生成订阅者，负责更新node.innerText
                this.$binds[value].push(new Watcher(node,"innerText"));
            }
        }
    }
})

function Watcher(node,prop){
    this.prop = prop;
    this.node = node;
}
Watcher.prototype.update=function(v){
    this.node[this.prop]=v;
}
export default Vue;